﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Domain.Services;
using Volo.Abp;
using Microsoft.Extensions.Logging;
using Volo.Abp.Uow;

namespace ERP.RBAC
{
    public class UserRoleServices : DomainService, IUserRoleServices
    {
        private readonly IRepository<UserRole, int> _userRoleRepository;
        private readonly IRepository<Users, int> _usersRepository;
        private readonly IRepository<Roles, int> _rolesRepository;
        private readonly ILogger<UserRoleServices> _logger;
        private readonly IUnitOfWorkManager _unitOfWorkManager;

        public UserRoleServices(
            IRepository<UserRole, int> userRoleRepository,
            IRepository<Users, int> usersRepository,
            IRepository<Roles, int> rolesRepository,
            ILogger<UserRoleServices> logger,
            IUnitOfWorkManager unitOfWorkManager)
        {
            _userRoleRepository = userRoleRepository;
            _usersRepository = usersRepository;
            _rolesRepository = rolesRepository;
            _logger = logger;
            _unitOfWorkManager = unitOfWorkManager;
        }

        public async Task<List<UserRole>> GetUserRoles(int userId)
        {
            try
            {
                _logger.LogInformation($"正在获取用户 {userId} 的角色列表");

                // 首先验证用户是否存在
                var user = await _usersRepository.FindAsync(u => u.Id == userId);
                if (user == null)
                {
                    _logger.LogWarning($"用户ID {userId} 不存在");
                    throw new UserFriendlyException($"用户ID {userId} 不存在");
                }

                // 直接使用 GetListAsync 获取用户的角色关系
                var userRoles = await _userRoleRepository.GetListAsync(ur => ur.UserId == userId);
                _logger.LogInformation($"用户 {userId} 有 {userRoles.Count} 个角色");

                return userRoles;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取用户 {userId} 的角色列表时发生错误");
                throw new UserFriendlyException($"获取用户角色失败: {ex.Message}");
            }
        }

        public async Task<int> AssignUserRoles(int userId, List<int> roleIds)
        {
            try
            {
                _logger.LogInformation($"开始为用户 {userId} 分配角色，角色数量：{roleIds?.Count ?? 0}");

                // 验证用户是否存在
                var user = await _usersRepository.FindAsync(u => u.Id == userId);
                if (user == null)
                {
                    _logger.LogWarning($"用户ID {userId} 不存在");
                    throw new UserFriendlyException($"用户ID {userId} 不存在");
                }

                // 验证角色是否都存在
                if (roleIds != null && roleIds.Any())
                {
                    // 使用 FindAsync 逐个验证角色是否存在
                    foreach (var roleId in roleIds)
                    {
                        var role = await _rolesRepository.FindAsync(r => r.Id == roleId);
                        if (role == null)
                        {
                            _logger.LogWarning($"角色ID {roleId} 不存在");
                            throw new UserFriendlyException($"角色ID {roleId} 不存在");
                        }
                    }
                }

                // 使用事务确保操作的原子性
                using (var uow = _unitOfWorkManager.Begin(requiresNew: true))
                {
                    try
                    {
                        // 删除用户现有的所有角色
                        await _userRoleRepository.DeleteAsync(ur => ur.UserId == userId);
                        _logger.LogInformation($"已删除用户 {userId} 的现有角色");

                        if (roleIds == null || !roleIds.Any())
                        {
                            _logger.LogInformation($"用户 {userId} 没有新的角色需要分配");
                            await uow.CompleteAsync();
                            return 0;
                        }

                        // 逐个插入新的用户角色关系
                        foreach (var roleId in roleIds)
                        {
                            var userRole = new UserRole
                            {
                                UserId = userId,
                                RoleId = roleId
                            };
                            await _userRoleRepository.InsertAsync(userRole);
                        }
                        
                        _logger.LogInformation($"成功为用户 {userId} 分配了 {roleIds.Count} 个角色");

                        // 提交事务
                        await uow.CompleteAsync();
                        return roleIds.Count;
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError(ex, $"在事务中分配角色时发生错误，正在回滚");
                        await uow.RollbackAsync();
                        throw;
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"为用户 {userId} 分配角色时发生错误");
                throw new UserFriendlyException($"分配角色失败: {ex.Message}");
            }
        }
    }
}

